import { ref, onBeforeMount, nextTick, type Ref } from 'vue'
import { setTableHeight, setFixedColumnWidth ,type setTableHeightParamsType} from '@/common/utils'
import { ElMessage as message } from 'element-plus'


type paramsType = {
  /**
   * 分页查询api请求函数，必选
   */
  listApiFunc: (params: any) => Promise<any>
  /**
   * 删除api请求函数
   */
  deleteApiFunc?: (params: any) => Promise<any>
  /**
  * 表头配置。用作处理需要显示的表头、配合actionList计算固定列宽度
  */
  columns?: Ref<tableColConfig[]>
  /**
   * 内容布局中除去表格、表格工具栏、搜索面板以外元素占据的高度，默认0
   */
  otherSectionHeight?: number
  /**
   * common/utils/setTableHeight函数的扩展参数，默认{}
   */
  setTableHeightExtendParams?: Omit<setTableHeightParamsType,('tableHeightRef' | 'otherSectionHeight')>
  /**
   * 最初时的页尺寸，默认20
   */
  initPageSize?: number
  /**
   * 表格固定列需要控制权限的动作值列表
   */
  actionList?: (string | string[])[]
  /**
   * 表格ref
   */
  tableRef?: Ref
  /**
   * 新增对话框ref
   */
  addRef?: Ref
  /**
   * 新增对话框ref
   */
  updateRef?: Ref
  /**
   * 查询面板折叠展开之后的回调
   */
  searchPanelcollapsed_after?: (h: number) => void
  /**
   * 打开新增对话框之前，返回true才打开
   */
  add_before?: () => boolean | void
  /**
   * 打开更新对话框之前，返回true才打开
   */
  update_before?: () => boolean | void
  /**
   * 删除之前，返回true才删除
   */
  delete_before?: () => boolean | void
  /**
   * 新增成功后的回调
   */
  add_after?: () => void
  /**
   * 更新成功后的回调
   */
  update_after?: () => void
  /**
   * 删除成功后的回调
   */
  delete_after?: () => void
  /**
   * 查询成功后的回调
   */
  query_after?: () => void
  /**
   * 点击查询按钮后的回调
   */
  search_after?: () => void
  /**
   * 点击重置按钮后的回调
   */
  reset_after?: () => void
}

/**
 * @description 表格增删查改混入。各个回调(xx_after,xx_before)均已处理基本的逻辑，预留回调只是为了让使用者处理其他非预知的逻辑
 * @param  ItemType 列表项类型，泛型传递
 * @param  config
 * @param  config.columns          表头配置，必选
 * @param  config.listApiFunc      分页查询api请求函数，必选
 * @param  config.deleteApiFunc    删除api请求函数，必选
 * @param  config.otherSectionHeight  内容布局中除去表格、表格工具栏、搜索面板以外元素占据的高度，默认0
 * @param  config.setTableHeightExtendParams  common/utils/setTableHeight函数的扩展参数，默认{}
 * @param  config.hasSearchPanel  该页面是否含有搜索面板，默认true
 * @param  config.initPageSize        最初时的页尺寸，默认20
 * @param  config.actionList          表格固定列需要控制权限的动作值列表
 * @param  config.tableRef 表格ref
 * @param  config.addRef  新增对话框ref
 * @param  config.updateRef  新增对话框ref
 * @param  config.searchPanelcollapsed_after   查询模板折叠展开之后的回调
 * @param  config.add_before  打开新增对话框之前，返回true才打开
 * @param  config.update_before 打开更新对话框之前，返回true才打开
 * @param  config.delete_before 删除之前，返回true才删除
 * @param  config.add_after    新增成功后的回调
 * @param  config.update_after 更新成功后的回调
 * @param  config.delete_after 删除成功后的回调
 * @param  config.query_after 查询成功后的回调
 * @param  config.search_after 点击查询按钮后的回调
 * @param  config.reset_after  点击重置按钮后的回调
 * @return 返回值参考自定义hook源码retrun。直接粘贴过去即可，根据需要使用
 * } 
 **/
export function useTableMixin<ItemType = objType>(config: paramsType) {

  const {
    listApiFunc, deleteApiFunc, otherSectionHeight = 0, setTableHeightExtendParams = {},
    initPageSize = 20, columns, actionList,
    searchPanelcollapsed_after, tableRef, addRef, updateRef, add_before, update_before, delete_before, add_after, update_after, delete_after, query_after, search_after, reset_after,
  } = config

  const current = ref(1)
  const size = ref(initPageSize)
  const total = ref(0)
  const filterOptions = ref<Partial<ItemType>>({})
  const tableHeight = ref<number>(200)
  const fixedColWidth = ref<number>(1)
  const tableList = ref<ItemType[]>()
  const addDialogVisible = ref(false)
  const updateDialogVisible = ref(false)
  const editRow = ref<ItemType>({} as any)
  const searchPanelHeight = ref(0)

  if (actionList && columns)
    fixedColWidth.value = setFixedColumnWidth(actionList, columns)

  onBeforeMount(() => {
    getData()
  })

  function handleSearchPanelcollapsed(h: number) {
    searchPanelHeight.value = h
    setTableHeight({ tableHeightRef: tableHeight, otherSectionHeight: h + otherSectionHeight, ...setTableHeightExtendParams })
    searchPanelcollapsed_after && searchPanelcollapsed_after(h)
  }


  async function getData() {
    try {
      let params: objType
      params = { page: { page: current.value, size: size.value }, cdt: filterOptions.value }
      const { data = {} } = await listApiFunc(params)
      tableList.value = data.list ? data.list : []
      total.value = data.total ? data.total : 0
      //console.log(data)
      // nextTick(()=>{
      //   setTableHeight({tableHeightRef:tableHeight,otherSectionHeight:searchPanelHeight.value+otherSectionHeight,...setTableHeightExtendParams})
      // })
      query_after && query_after()
    } catch (error) {
      console.log(error, 'useTableMixin getData err')
    }

  }

  function handleSearch(value: Partial<ItemType>) {
    filterOptions.value = value
    getData()
    search_after && search_after()
  }

  function handleReset() {
    current.value = 1
    size.value = initPageSize
    filterOptions.value = {}
    getData()
    if (tableRef) tableRef.value?.reset()
    reset_after && reset_after()
  }

  function handlePaginationChange({ page, size: s }: { page?: number, size?: number }) {
    if (page)
      current.value = page
    if (s)
      size.value = s
    getData()
  }

  function handleColumnsChange(list: any[]) {
    //console.log(list)
    if (columns) columns.value = list
  }

  async function handleAddCommit() {
    if (addRef) {
      const isSuccess = await addRef.value?.formCommit()
      if (isSuccess) {
        addDialogVisible.value = false
        message.success('新增成功')
        getData()
        add_after && add_after()
      }
    }
  }


  async function handleUpdateCommit() {
    if (updateRef) {
      const isSuccess = await updateRef.value?.formCommit()
      if (isSuccess) {
        updateDialogVisible.value = false
        message.success('更新成功')
        getData()
        update_after && update_after()
      }
    }
  }


  function handleAdd() {
    if (add_before) {
      if (!add_before()) return
    }
    //console.log(row)
    addDialogVisible.value = true
    if (addRef) {
      nextTick(() => {
        if (addRef.value && addRef.value?.init) addRef.value.init()
      })
    }
  }

  function handleUpdate(row: any) {
    //console.log(row)
    editRow.value = row
    if (update_before) {
      if (!update_before()) return
    }
    updateDialogVisible.value = true
    if (updateRef) {
      nextTick(() => {
        if (updateRef.value && updateRef.value?.init) updateRef.value.init()
      })
    }
  }


  async function handleDelete(row: any) {
    editRow.value = row
    if (delete_before) {
      if (!delete_before()) return
    }
    if (deleteApiFunc) {
      const res = await deleteApiFunc({ id: row.id })
      if (res && res.code) {
        message.success('删除成功')
        getData()
        delete_after && delete_after()
      }
    }
  }

  return {
    current,     // 当前页码
    size,     // 页尺寸
    total,        // 总条数
    filterOptions,  // 查询条件
    getData,        // 获取页数据的方法
    tableHeight,  // 表格高度
    addDialogVisible, //新增对话框显示隐藏状态
    updateDialogVisible, //更新对话框显示隐藏状态
    tableList,   // 表格数据
    editRow,    // 当前编辑数据
    handleSearchPanelcollapsed,  //search-panel组件的 @collapsed 的处理函数
    handleSearch,   // 搜索处理函数
    handleReset,   // 重置表格数据处理函数
    handlePaginationChange,  // 处理分页器变化处理函数
    handleColumnsChange,    // 表头变化组件的处理函数
    handleAdd,     // 点击新增按钮回调
    handleUpdate,   // 点击更新按钮回调
    handleDelete,   // 删除处理函数
    handleAddCommit,   // 新增提交处理函数
    handleUpdateCommit,  // 更新提交处理函数
  }
}